#pragma once
#include "stdafx.h"
#include "testing.h"

/*
This exercise tests the use of static variables and functions.
(i) Write an interface class RandomNumberGenerator that has a function to
generate a uniformly distributed random number.
(ii) Write an implementation of RandomNumberGenerator that uses the
mt19937 class. This design pattern of implementing an interface by simply calling another class to do all the work is called delegation.
(iii) Write a static function on the RandomNumberGenerator class called setDefault that sets the current default RandomNumberGenerator instance.
Note that you should use a shared_ptr<RandomNumberGenerator> as
the parameter to setDefault.
(iv) Write a static function randUniform on RandomNumberGenerator that
allows the user to generate a uniformly distributed random number without needing to create a RandomNumberGenerator.
(v) Add a non-static setAsDefault function to RandomNumberGenerator
that sets the current random number generator to be used as the default
random number generator. You will need to use the this keyword.
(vi) In what ways, if any, do you think this improves upon the existing functions in matlib?

 */
class RandomNumberGenerator {
public:
    void setDefault(std::shared_ptr<RandomNumberGenerator> generator) {
        defaultGenerator = generator;
    }
    double randUniform() {
        if (defaultGenerator == nullptr) {
            throw std::runtime_error("No default random number generator set");
        }
        return defaultGenerator->randUniform();
    }
    void setAsDefault() {
        setDefault(std::shared_ptr<RandomNumberGenerator>(this));
    }
private:
    std::shared_ptr<RandomNumberGenerator> defaultGenerator; 
};